<template>
  <div class="hl0109-split-drag-pane" :class="[split,active?'text-select-none':'']" :style="domStyle" @mouseup="onMouseUp" @mousemove="onMouseMove" @touchmove="handleTouchMove" @touchend="handleTouchEnd" @touchstart="handleTouchStart">
    <resizer v-if="!isFirst" :className="className" :split="getParentSplit()" @mousedown.native="onMouseDown" :gSpan="gSpan" ref="resizer"></resizer>
    <slot></slot>
  </div>
</template>
<script>
import Resizer from './resizer.vue'
export default {
  name: 'splitDragPane',
  components: {
    Resizer
  },
  provide(){
    return {
      getParentPane:()=>{ return this }
    }
  },
  inject: {
    getParentPane:{
      from:'getParentPane',
      value:'getParentPane',
      default:null,
    }
  },
  props: {
    //面板分割方式,vertical竖着分割,horizontal横着分割
    split: {
      type: String,
      validator(value) {
        return ['vertical', 'horizontal'].indexOf(value) >= 0
      },
      default: 'vertical'
    },
    //支持像素与百分比
    minPercent: {
      default: '50px'
    },
    //支持像素与百分比
    defaultPercent: {},
    className: String,
    vmid: String,
    span:{
      type:Number,
      default:0
    },
  },
  data() {
    return {
      percent: this.getDefaultPercent(this),
      active: false,
      moveStart: 0,
      currentPanel: this,
      childrenPanel: [],
    }
  },
  computed: {
    domStyle() {
      let type = this.getParentSplit() === 'vertical' ? 'width' : 'height'
      let value = this.percent + '%'
      let minValue = (this.minPercent + '').includes('px') ? this.minPercent : (this.minPercent + '').replace('%', '') + '%'
      let obj={
        [type]: value,
        ['min-' + type]: minValue
      }
      if(!this.isFirst){
        let marginX = this.getParentSplit() === 'vertical' ? 'marginLeft' : 'marginTop'
        obj[marginX]=this.gSpan+'px'
      }
      return obj
    },
    gSpan(){
      let val=0
      if (this.getParentPane) {
        val=this.getParentPane().gSpan
      }
      if(this.span){
        val=this.span
      }
      return val||0
    },
    isFirst() {
      let value = false
      let parent = this.getParentPane ? this.getParentPane() : null
      if (parent) {
        let children = parent.childrenPanel
        if (children[0] === this) {
          value = true
        }
      }
      if(!this.getParentPane){
        value = true
      }
      return value
    },
    isLast() {
      let value = false
      let parent = this.getParentPane ? this.getParentPane() : null
      if (parent) {
        let children = parent.childrenPanel
        if (children[children.length-1] === this) {
          value = true
        }
      }
      if(!this.getParentPane){
        value = true
      }
      return value
    },
  },
  created() {
    if(!this.$set){
      this.$set=function (obj,key,val){
        obj[key]=val
      }
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    init(){
      if (this.getParentPane) {
        this.percent= this.getDefaultPercent(this)
        if(!this.getParentPane().childrenPanel.includes(this)){
          this.getParentPane().childrenPanel.push(this)
          this.$nextTick(()=>{
            let childrenPanel=this.getParentPane().childrenPanel
            if(0<childrenPanel.indexOf(this)&&childrenPanel.length>1){
              this.percent=this.percent - this.getParentPane().getDomPercent(this.gSpan)
              if(childrenPanel.indexOf(this)===childrenPanel.length-1){
                let sum=0
                let list=[]
                childrenPanel.forEach((item,index)=>{
                  sum+=item.percent
                  if(index>0){
                    sum+=this.getParentPane().getDomPercent(item.gSpan)
                  }
                  if(item.percent>this.getMinPercent(item)){
                    list.push(item)
                  }
                })
                let syVal=100-sum
                let absSyVal=Math.abs(syVal)
                list.forEach((item,index)=>{
                  let cyVal=item.percent-this.getMinPercent(item)
                  if(syVal<0){
                    if(cyVal>absSyVal){
                      item.percent=item.percent-absSyVal
                      syVal=0
                    }
                  }
                  if(syVal>0){
                    if(index===list.length-1){
                      item.percent=item.percent+absSyVal
                      syVal=0
                    }
                  }
                })
              }
            }
          })
        }
      }
    },
    getParentSplit() {
      let value = this.split
      if (this.getParentPane) {
        value = this.getParentPane().split
      }
      return value
    },
    onMouseDown(e) {
      if (this.getParentPane) {
        this.getParentPane().currentPanel = this
        this.getParentPane().active = true
        this.getParentPane().moveStart = this.getParentSplit() === 'vertical' ? e.pageX : e.pageY
      }
    },
    onMouseUp(e) {
      if (this.getParentPane) {
        this.getParentPane().currentPanel = this.getParentPane()
        this.getParentPane().active = false
        this.active = false
      }
    },
    getDomVal(vmDom) {
      let dom = vmDom.$el
      let domVal = this.split === 'vertical' ? dom.offsetWidth : dom.offsetHeight
      return domVal
    },
    getDomPercent(val) {
      let pVal = this.getDomVal(this)
      return (val / pVal)*100
    },
    getAllVmSum(leftVal, rightVal) {
      let sumVal = 0
      let children = this.childrenPanel
      let leftVmDom = children[children.indexOf(this.currentPanel) - 1]
      let rightVmdom = this.currentPanel
      children.forEach((item) => {
        if (item === leftVmDom) {
          sumVal += leftVal
        } else if (item === rightVmdom) {
          sumVal += rightVal
        } else {
          sumVal += this.getDomPercent(this.getDomVal(item))
        }
      })
      return sumVal
    },
    getMinPercent(vmdom) {
      let vmVal = vmdom.minPercent + ''
      if (!vmVal.includes('px')) {
        return parseFloat(vmVal)
      } else {
        if (vmdom.getParentPane && vmdom.getParentPane().$el) {
          return parseFloat(vmVal) / this.getDomVal(vmdom.getParentPane())
        }
      }
    },
    getDefaultPercent(vmdom) {
      let vmVal = vmdom.defaultPercent + ''
      if (!vmVal.includes('px')) {
        return parseFloat(vmVal)
      } else {
        if (vmdom.getParentPane && vmdom.getParentPane().$el) {
          vmVal=vmVal.replace("calc","").replace(/%/g,'')
          let list=vmVal.replace(/ /g,'').replace(/\(/g,'').replace(/\)/g,'')
          list=list.split("-").map(item=>item.split("+")).flat()
          list.forEach((item,index)=>{
            if(item&&item.includes('px')){
              let val=vmdom.getParentPane().getDomPercent(parseFloat(item))
              vmVal=vmVal.replace(item,val)
            }
          })
          let sum=eval(vmVal)
          if(sum<parseFloat(this.getMinPercent(this))){
            sum=parseFloat(this.getMinPercent(this))
          }
          return sum
        }
      }
    },
    getIsM(val, vmdom) {
      let minVal = this.getMinPercent(vmdom)
      return val > minVal
    },
    onMouseMove(e,isTouch) {
      if (!isTouch&&(e.buttons === 0 || e.which === 0)) {
        if (this.getParentPane) {
          this.getParentPane().active = false
        }
        this.active = false
      }
      //父节点执行
      if (this.active) {
        let mouseValue = this.split === 'vertical' ? e.pageX : e.pageY
        let moveVal = this.moveStart - mouseValue

        let children = this.childrenPanel
        let leftVmDom = children[children.indexOf(this.currentPanel) - 1]
        if (!leftVmDom) {
          return
        }
        let rightVmdom = this.currentPanel

        let leftVmDomVal = this.getDomVal(leftVmDom)
        let rightVmDomVal = this.getDomVal(rightVmdom)

        let leftSumValue = leftVmDomVal - moveVal
        let rightSumValue = rightVmDomVal + moveVal

        let leftPercent = this.getDomPercent(leftSumValue)
        let rightPercent = this.getDomPercent(rightSumValue)

        let gSpanSum = 0
        this.childrenPanel.forEach((item,index)=>{
          if(index>0){
            gSpanSum+=this.getDomPercent(item.gSpan)
          }
        })
        leftPercent = this.getIsM(leftPercent, leftVmDom) ? leftPercent : this.getMinPercent(leftVmDom)
        rightPercent = this.getIsM(rightPercent, rightVmdom) ? rightPercent : this.getMinPercent(rightVmdom)

        //判断是否超出
        let yVal = Math.ceil((this.getAllVmSum(leftPercent, rightPercent + gSpanSum) - 100) * 100) / 100
        if (leftPercent - yVal >= this.getMinPercent(leftVmDom)) {
          leftPercent = leftPercent - yVal
        } else if (rightPercent - yVal >= this.getMinPercent(rightVmdom)) {
          rightPercent = rightPercent - yVal
        }

        this.$set(leftVmDom, 'percent', leftPercent)
        this.$set(rightVmdom, 'percent', rightPercent)
        this.moveStart = mouseValue
        leftVmDom.$emit('change', {vmid: leftVmDom.vmid, value: leftPercent, vmdom: leftVmDom}, {
          vmid: rightVmdom.vmid,
          value: leftPercent,
          vmdom: rightVmdom
        })
        rightVmdom.$emit('change', {vmid: leftVmDom.vmid, value: leftPercent, vmdom: leftVmDom}, {
          vmid: rightVmdom.vmid,
          value: leftPercent,
          vmdom: rightVmdom
        })
        //this.$emit('change',{vmid:leftVmDom.vmid,value:leftPercent,vmdom:leftVmDom},{vmid:rightVmdom.vmid,value:leftPercent,vmdom:rightVmdom})
      }
    },
    handleTouchStart(event) {
      event.pageX=event.touches[0].pageX
      event.pageY=event.touches[0].pageY
      
      if(this.$refs.resizer){
        var resizerDom=this.$refs.resizer.$el
        if(event.target===resizerDom){
          this.onMouseDown(event)
        }else if(window.getComputedStyle){
          var domInfo= resizerDom.getBoundingClientRect()
          let isHave=false
          if(this.split==='vertical'){
            if(0<event.pageX-domInfo.left&&event.pageX-domInfo.left<30){
              isHave=true
            }
          }else{
            if(0<event.pageY-domInfo.top&&event.pageY-domInfo.top<30){
              isHave=true
            }
          }
          if(isHave){
            this.onMouseDown(event)
          }
        }
      }
    },
    handleTouchMove(event) {
      // 触摸移动时的处理逻辑
      event.pageX=event.touches[0].pageX
      event.pageY=event.touches[0].pageY
      this.onMouseMove(event,true)
    },
    handleTouchEnd(event) {
      // 触摸结束时的处理逻辑
      this.onMouseUp(event)
    }
  },
}
</script>

<style scoped>
.hl0109-split-drag-pane {
  width: 100%;
  height: 100%;
  position: relative;
}

.hl0109-split-drag-pane.vertical {
  display: flex;
}

.hl0109-split-drag-pane.horizontal{
  display: flex;
  flex-direction: column;
}

.text-select-none {
  -webkit-user-select: none; /* Safari */
  -ms-user-select: none; /* IE 10+ and Edge */
  user-select: none; /* Standard syntax */
}

.text-select-none * {
  -webkit-user-select: none; /* Safari */
  -ms-user-select: none; /* IE 10+ and Edge */
  user-select: none; /* Standard syntax */
}
</style>
